# 前言
Teleport 内置组件的功能是可以将一个组件内部的一部分 vnode 元素 “传送” 到该组件的 DOM 结构外层的位置去挂载。那什么情况下可能会用到该组件呢?如果开发过组件库的小伙伴可能深有体会,当我们开发全局 Dialog 组件来说,我们希望 Dialog 的组件可以渲染到全局 <body> 标签上,这个时候我们写的 Dialog 组件的源代码可能是这样的:
html
复制代码<template>
<div>
<!-- 这里是 dialog 组件的容器逻辑 -->
</div>
</template>
<script>
export default {
mounted() {
// 在 dom 被挂载完成后,再转移到 body 上
document.body.appendChild(this.$el);
},
destroyed() {
// 在组件被销毁之前,移除 DOM
this.$el.parentNode.removeChild(this.$el);
}
}
</script>
@前端进阶之旅: 代码已经复制到剪贴板
这么做确实可是实现挂载到特定容器中,但这样一方面让 Dialog 组件内部需要维护复杂的 DOM 节点转换的逻辑,另一方面导致了浏览器需要进行 2 次刷新操作,一次初始化挂载,一次迁移。
所以 Vue 3 很贴心的为我们了提供了 Teleport 组件,帮助我们以简便的方式高性能的完成节点的转移工作:
html
复制代码<Teleport to="body">
<div class="modal">
<p>Hello from the modal!</p>
</div>
</Teleport>
@前端进阶之旅: 代码已经复制到剪贴板
接下来我们将一起探秘 Teleport 组件是如何实现 “传送” 挂载的。
# Teleport 的挂载
先来看看 Teleport 组件的源码定义:
export const TeleportImpl = {
// 组件标记
__isTeleport: true,
process(...) {
// ...
// 初始化的逻辑
if (n1 === null) {
// ...
} else {
// ...